var express = require('express');
var app = express();
const FS = require('fs');

var cmd = require('node-cmd');
// 用于处理post请求的消息体
const bodyParser = require('body-parser');
// 使用body-parser,支持编码为json的请求体
app.use(bodyParser.json());
// 支持编码为表单的消息体
app.use(bodyParser.urlencoded({
    extended: true
}))

var path = require('path');
var fs = require('fs')

var multer = require('multer');
var objMulter = multer({dest: './upload'}); //设置上传的的图片保存目录
app.use(objMulter.any());

var ejs = require('ejs');
app.set('views', path.join(__dirname, '/views'));
app.engine('html', require('ejs').__express);
app.set('view engine', 'html');

app.use(express.static(__dirname + '/static'));
app.use(express.static(__dirname + '/upload'));

const Articles = require('./db').Articles;

const ci = require('miniprogram-ci')


var NodePaths = "fanxing-shop-app"


// 首页
app.get('/', function (req, res) {
    Articles.all((err, articles) => {
        if (err) return next(err);
        res.render('index', {list: articles})
    })
})
// 创建 项目
app.post('/article/add', (req, res, next) => {
    Articles.create({
        "title": req.body.title ? req.body.title : '',
        "appid": req.body.appid ? req.body.appid : '',
        "keys": req.body.keys ? req.body.keys : ''
    }, (err, data) => {
        if (err) return next(err);
        res.json({
            code: 200,
            msg: "添加成功",
        })
    });
});
// 删除 项目
app.post('/article/del', (req, res, next) => {
    var id = req.body.id
    Articles.delete(id, (err, data) => {
        if (err) return next(err);
        res.json({
            code: 200,
            msg: "删除成功",
        })
    });
});
// 文件上传
app.post('/upload', function (req, res, next) {
    if (req.files.length == 0) {
        return res.json({
            code: 500,
            msg: "不能上传空文件"
        })
    }
    const newname = req.files[0].path + path.parse(req.files[0].originalname).ext
    fs.rename(req.files[0].path, newname, function (err) {
        if (err) {
            res.json({
                code: 500,
                msg: "上传失败"
            })
        } else {
            res.json({
                code: 200,
                msg: "上传成功",
                name: newname
            })
        }
    })
})
// 编译打包到微信
app.post('/addwx', async function (req, res) {
    Articles.find(req.body.id, (err, articles) => {
        if (err) return next(err);
        wx(articles, function (params) {
            res.json(params)
        })
    })
})

// 编译代码
app.post('/compile', async function (req, res) {
    console.log("开始编译");
    // 判断 项目是否存
    var exists = fs.existsSync('./' + NodePaths)
    if (!exists) {
        console.log('目录不存在的情况');
        res.json({
            code: 500,
            msg: "当面项目不存在,请检查项目：" + NodePaths,
        })
    }

    // 判断依赖目录 是否存在
    var exists = fs.existsSync('./' + NodePaths + '/node_modules')
    if (exists) {
        console.log('已安装依赖');
    } else {
        console.log('开始安装依赖');
        // 安装依赖
        var err = cmd.runSync('cd ./' + NodePaths + '& npm i')
        console.log(err,"err")

    }

    console.log('依赖安装完成,开始编译');
    const syncDir = cmd.runSync('cd ./' + NodePaths + ' & npm run build:mp-weixin');
    console.log(`
            Sync 失败 ${syncDir.err}
            Sync stderr:  ${syncDir.stderr}
            Sync Data ${syncDir.data}
        `);
    if (syncDir.err) {
        res.json({
            code: 500,
            msg: syncDir.err,
        })
    } else {
        res.json({
            code: 200,
            msg: "编译成功",
        })
    }
})

async function wx(data, Callback) {

    var pathName = path.join(__dirname, '/' + NodePaths + '/dist/build/mp-weixin/')
    // 确保当前上传目录成功存在
    fs.exists(pathName, function (exists) {
        console.log(exists ? "创建成功" : "创建失败");
        if (exists) {
            // 存在目录
            // var paths = './' + NodePaths + '/dist/build/mp-weixin/' + 'common/vendor.js'
            var paths = './' + NodePaths + '/dist/build/mp-weixin/' + 'common/vendor.js'

            // 处理上传玩的情况  修复配置文件  "开始替换配置","appid","tenantCode"
            console.log("开始替换配置","appid","tenantCode",paths);

            replaceFile(paths, "tenantCode", "123456789", (con) => {
                console.log(con, "====================================================================",data);
                // 123456
                try {
                    const project = new ci.Project({
                        appid: data.appid,
                        type: 'miniProgram',
                        projectPath: pathName,
                        privateKeyPath: path.join(__dirname, '/upload/' + data.keys),
                        ignores: ['node_modules/**/*'],
                    })

                    ci.upload({
                        project,
                        version: '2.1.4',
                        desc: data.title,
                        setting: {
                            es6: true,
                        },
                        robot: 20,
                        // onProgressUpdate: console.log,
                    }).then(res => {
                        // console.log(res);
                        Callback({
                            code: 200,
                            msg: "上传成功",
                        })
                    }).catch(error => {
                        // console.log(error);
                        Callback({
                            code: 500,
                            msg: error,
                        })
                    })
                } catch (error) {
                    Callback({
                        code: 500,
                        msg: error,
                    })
                }
            })

        } else {
            // 目录不存在
            Callback({
                code: 500,
                msg: "目录不存在",
            })
        }
    });


}

function replaceFile(filePath, sourceRegx, targetStr, Callback) {
    FS.readFile(filePath, function (err, data) {
        console.log("替换开始")
        if (err) {
            return err;
        }
        let str = data.toString(); // str是总文件 strig类型的
        var s = str.indexOf(sourceRegx) // s 查找的的下标
        var o = str.substring(s, s+50) // 从tenantCode + 50个字节的后面的数据
        var pattern =/((?<!\\)['"`])(.*?)\1/ // 单双引号正则
        var mathStr = pattern.exec(o)
        var suorce = mathStr ? mathStr[2] : '123456'

        str = str.replace(suorce, targetStr); // 替换内容
        // 写入数据
        FS.writeFile(filePath, str, function (err) {
            if (err) return err;
            Callback({
                code: 200,
                msg: "配置修改成功",
            })
        });
    });
}


var server = app.listen(8081, function () {
    var port = server.address().port
    console.log("运维端小程序发版工具，访问地址为 http://127.0.0.1:%s", port)
})
